import { routerRedux } from 'dva/router';
import { connect as connectDva } from 'dva';
import moment from 'moment';
import store from 'store';
import lzstring from 'lz-string';
import _ from 'lodash';
import { restoreValues} from '../components/modalForm';

//moment默认格式化为YYYY-MM-DD[T]HH:mm:ss.SSS[Z],mysql数据存储有错误
moment.fn.toJSON = function () {
    return moment(this).utc().format('YYYY-MM-DD HH:mm:ss');
};


// 日期格式化
/*eslint no-extend-native:0*/
Date.prototype.format = function format(input) {
    let res = input;
    const o = {
        'M+': this.getMonth() + 1,
        'd+': this.getDate(),
        'h+': this.getHours(),
        'H+': this.getHours(),
        'm+': this.getMinutes(),
        's+': this.getSeconds(),
        'q+': Math.floor((this.getMonth() + 3) / 3),
        S: this.getMilliseconds()
    };
    if (/(y+)/.test(res)) {
        res = res.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (let k in o) {
        if (new RegExp('(' + k + ')').test(res)) {
            res = res.replace(RegExp.$1, RegExp.$1.length === 1
                ? o[k]
                : ('00' + o[k]).substr(('' + o[k]).length));
        }
    }
    return res;
};

_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;

export function carryFunc(fun, ...args) {
    if (typeof fun === 'function') {
        fun(...args);
    }
}

export function dayUnixParse(number, format = 'YYYY-MM-DD HH:mm:ss', unit = 'ms') {
    if (typeof number !== 'number') {
        throw new Error('number参数的类型必须是"Number"!');
    }
    if (unit !== 'ms' && unit !== 's') {
        throw new Error('unit参数的值只能是"s"或者"ms"，默认是"ms"!');
    }
    if (unit === 's') {
        number *= 1000;
    }
    return moment(number).format(format);
}

export const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout || 0));

export const diifTimer = ({
                              from,
                              to = moment(),
                              unit = 'days'
                          }) => {
    if (from) {
        if (typeof from === 'string') {
            from = moment(from);
        }
        return to.diff(from, unit);
    }
    throw new Error('from 参数必填，从何时开始计算时间差？');
};

export const jump = (dispatch, pathname, query, state) => {
    dispatch(routerRedux.push({
        pathname,
        state,
        query,
    }));
};

const defaultMapDispatchToProps = (dispatch) => {
    return {
        dispatch,
        action: (type, payload, ...args) => {
            dispatch({ type, payload, exts: args });
        },
    };
};

/**
 * 扩展redux中connect
 * 组件属性中会多一个action的fn,用法action(type,payload)
 * @param mapStateToProps
 * @param mapDispatchToProps
 * @param mergeProps
 * @param args
 */
export function connect(mapStateToProps = _.noop, mapDispatchToProps, mergeProps, ...args) {
    const mapS2P = (state) => {
        const props = mapStateToProps(state) || {};
        if (props.ns) {
            const { loading: { effects } = {} } = state;
            if (effects) {
                const ns = `${props.ns}/`;
                const len = ns.length;
                const loadings = _.reduce(effects, (res, v, k) => {
                    if (_.startsWith(k, ns)) {
                        res[k.substr(len)] = v;
                    }
                    return res;
                }, {});
                return { loadings, ...props };
            }
        }
        return props;
    };
    return connectDva(
        ...[
            mapS2P,
            mapDispatchToProps || defaultMapDispatchToProps,
            mergeProps,
            ...args
        ]);
}

/**
 * 清理缓存数据
 * @param obj
 * @param keys(undefined或true时用于集合取所有,false 用于单对象,多个key 用于对象)
 */
export function pureCache(obj = {}, keys) {
    if (keys === undefined || keys === true) {
        return _.reduce(obj, (r, v, k) => {
            const { content } = v || {};
            r[k] = content;
            return r;
        }, {});
    } else if (!keys) {
        const { content } = obj;
        return content;
    } else {
        return _.reduce(keys.split(','), (r, v) => {
            const { content } = obj[v] || {};
            r[v] = content;
            return r;
        }, {});
    }
}

const TOKEN = 'token';
const URL = 'url';
const KEY_PATH = 'keyPath';
const USER = 'user';
/**
 * 获取token
 * @param forHeader
 * @returns {*}
 */
export function getToken(forHeader) {
    const token = sessionStorage[TOKEN] || localStorage[TOKEN];
    if (token) {
        //return forHeader ? `Bearer ${token}` : token;
        return token;
    }
    return forHeader ? '' : token;
}

/**
 * 保存token
 * @param token
 * @param remeber
 */
export function saveToken(token, remeber) {
    (remeber ? localStorage : sessionStorage)[TOKEN] = token;
}

/**
 * 移除token
 */
export function removeToken() {
    sessionStorage.removeItem(TOKEN);
    localStorage.removeItem(TOKEN);
    sessionStorage.removeItem(URL);
    localStorage.removeItem(URL);
    sessionStorage.removeItem(USER);
    localStorage.removeItem(USER);
    sessionStorage.removeItem(KEY_PATH);
    localStorage.removeItem(KEY_PATH);
}

/**
 * token状态
 * @returns {boolean}
 */
export function loginStatus() {
    if (!storeGet(USER)) {
        return false;
    } else {
        return true;
    }
}

//设置获取用户信息的方式
export const storeGet = (key) => {
    const v = store.get(key);
    if (v) {
        try {
            return JSON.parse(lzstring.decompress(v));
        } catch (e) {
            return '';
        }
    }
    return v;
};

export const storeSet = (key, val) => {
    store.set(key, lzstring.compress(JSON.stringify(val)));
    return val;
};

/**
 * 文件大小单位
 * @param bytes
 * @returns {*}
 */
export function fileSize(bytes) {
    if (bytes === undefined || bytes === null) {
        return '';
    }
    if (bytes === 0) return '0 B';
    const k = 1000;// or 1024
    const sizes = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    //eslint-disable-next-line
    return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}

/**
 * 序列化模块数据
 * @param modules
 */
export function normalizedModules(modules = []) {
    const root = _.map(
        _.remove(modules, (module) => !module.pid),
        ({ id, code, name, url, icon: ico }) => ({
            id,
            code,
            name,
            url,
            ico,
            children: []
        })
    );
    if (modules.length > 0) {
        /* 如果剥离根模块后还有子模块 */
        _.map(modules, ({ id, pid, code, name, url, icon: ico }) => {
            const parent = _.find(root, ['id', pid]);
            const child = {
                id,
                code,
                name,
                url: url || '/sys/user',
                ico,
            };
            if (parent) {
                parent.children.push(child);
            } else {
                root.push(child);
            }
        });
    }
    console.log('root', root);
    return root;
}
/**
 * 获得menu信息中的跳转目标(第一个)
 * @param first
 * @returns {*}
 */
export function getMenuTarget([first = {}]) {
    const { url: parentUrl, children, code: parentCode } = first;
    if (children && children.length > 0) {
        /* 有子菜单 */
        const { url, code } = children[0];
        return {
            url,
            keyPath: [code, parentCode],
        };
    }
    /* 没有子菜单 */
    return {
        url: parentUrl,
        keyPath: [parentCode],
    };
}
export function fieldPathValue(obj, res, path) {
    const isArray = _.isArray(obj);
    _.each(obj, (value, key) => {
        let currentPath = isArray
            ? `[${key}]`
            : `${key}`;
        if (path) {
            currentPath = isArray
                ? `${path}${currentPath}`
                : `${path}.${currentPath}`;
        }
        if (_.isObject(value)) {
            fieldPathValue(value, res, currentPath);
        } else {
            res[currentPath] = { value };
        }
    });
}
export function changeStatus({data, put, ns}, type) {
    if (_.isFunction(put)) {
        const status = type ? 1 : 0;
        /**
         * TODO 员工列表中roleId字段需要去掉
         * TODO memberId -> id
         * TODO role.roleId 值类型由数字改为字符串
         **/
        delete data.roleId;
        const d = restoreValues(data);
        put({
            type: `${ns}/editorOk`,
            payload: {
                isNew: false,
                values: {...d, status},
            }
        });
    }
}


export function turnNumber(target) {
    return !_.isNumber(target) ? parseInt(target, 10) : target;
}


const checkMin = (min = 0) => (rule, value, callback) => {
    if (value >= min) {
        callback();
    } else {
        callback(`不能小于${min}!!`);
    }
};
export const minRule = (min = 0) => ({ validator: checkMin(min) });

export const requiredRule = {
    required: true,
    message: '必填项',
};
export const numberRule = {
    type: 'number',
    message: '请输入数字',
};

/**
 * 验证手机号码和固定号码
 * @param message
 * @returns {{pattern: RegExp, message: string}}
 */
const phoneAndTel = (message = '请输入合法的手机号码或固定号码') => {
    return {
        pattern: /^(1\d{10}|0\d{2,3}-\d{7,8})$/,
        message,
    };
};

export const phoneRule = {
    validator: (rule, value, callback) => {
        const { pattern, message } = phoneAndTel();
        if (pattern.test(value)) {
            callback();
        } else {
            callback(message);
        }
    }
};

